#include "tasks.h"
#include <stdlib.h>
#include <vector>
using namespace std;

void TaskCPU(int pid, vector<int> params) { // params: n
	uso_CPU(pid, params[0]); // Uso el CPU n milisegundos.
}

void TaskIO(int pid, vector<int> params) { // params: ms_pid, ms_io,
	uso_CPU(pid, params[0]); // Uso el CPU ms_pid milisegundos.
	uso_IO(pid, params[1]); // Uso IO ms_io milisegundos.
}

void TaskAlterno(int pid, vector<int> params) { // params: ms_pid, ms_io, ms_pid, ...
	for(int i = 0; i < (int)params.size(); i++) {
		if (i % 2 == 0) uso_CPU(pid, params[i]);
		else uso_IO(pid, params[i]);
	}
}
void TaskConsola(int pid, vector<int> params) { // params: n, bmin, bmax
	int n = params[0];
	int bmin = params[1];
	int bmax = params[2];
	int modulo = bmax - bmin +1;
	unsigned int seed;
	seed = (unsigned int)(time(NULL));
	srand(seed);
	for(int i = 0; i < n; i++) {
		uso_IO(pid, rand() % modulo + bmin);
		
	}
}
//helen
void TaskBatch(int pid, vector <int> params) { // params: total_cpu, cant_bloqueos
    std::vector<bool> bloqueos;
    int i = 0;
    int random= 0;
    int total_cpu = params[0];
    int cant_bloqueos = params[1];
    for (i = 0; i < total_cpu ; i++){
        bloqueos.push_back(false);
    }

    int temp;
	for(int i = 0; i < cant_bloqueos; i++){
		temp = rand()%total_cpu;
		while(bloqueos[temp]){
			temp = rand()%total_cpu;
		}
		bloqueos[temp] = true;
	}
	
	for (i = 0; i < total_cpu; i++){
           if (bloqueos[i] == true){
            uso_IO(pid, 1);
           }
           else {
            uso_CPU(pid, 1);
           }
    }
}
//helen
/*
void TaskBatch(int pid, vector <int> params) { // params: total_cpu, cant_bloqueos
    std::vector<bool> bloqueos;
    int i = 0;
    int random= 0;
    int total_cpu = params[0];
    int cant_bloqueos = params[1];
    for (i = 0; i < total_cpu ; i++){
        bloqueos.push_back(false);
    }

    for (i = 0; i < cant_bloqueos; i++){
        random = rand() % total_cpu;
        if (bloqueos[random] == true){
            i--;
        }
        else {
            bloqueos[random] = true;
        }
    }
   for (i = 0; i < total_cpu; i++){
           if (bloqueos[i] == true){
            uso_IO(pid, 1);
           }
           else {
            uso_CPU(pid, 1);
           }
    }
}
*/
/*
//nuevo algoritmo modificado
void TaskBatch(int pid, vector <int> params) {
 int total_cpu = params[0];
    bool bloqueos[total_cpu];
    int i = 0;
    for (i = 0; i < total_cpu ; i++){
        bloqueos[i] = false;
    }
    int bloqueos2[total_cpu];
    for (i = 0; i < total_cpu ; i++){
        bloqueos2[i] = i;
    }

    int random= 0;
    int cant_bloqueos = params[1];
    int j = total_cpu -1;
    int limite = total_cpu;
    i = cant_bloqueos;
    int temp;

    while (i != 0){
        random = rand() % limite;
        temp = bloqueos2[j];

        bloqueos2[j] = bloqueos2[random];
        bloqueos2[random] = temp;

        j--;
        i--;
        limite --;
        
    }
   
   j = total_cpu -1;
   i = 0;
   for (;cant_bloqueos > 0; cant_bloqueos--){
    i = bloqueos2[j];
    bloqueos[j] = true;
   }


   for (i = 0; i < total_cpu; i++){
           if (bloqueos[i] == true){
            uso_IO(pid, 1);
           }
           else {
            uso_CPU(pid, 1);
           }
    }
}
*/
void tasks_init(void) {
	/* Todos los tipos de tareas se deben registrar acá para poder ser usadas.
	 * El segundo parámetro indica la cantidad de parámetros que recibe la tarea
	 * como un vector de enteros, o -1 para una cantidad de parámetros variable. */
	register_task(TaskCPU, 1);
	register_task(TaskIO, 2);
	register_task(TaskAlterno, -1);
	register_task(TaskConsola, 3);
	register_task(TaskBatch, 2);
}
